#include "TaskQueue.hpp"

namespace tp{

TaskQueue::TaskQueue(size_t queSize)
    :_que()
     ,_queSize(queSize)
     ,_mutex()
     ,_notFull(_mutex)
     ,_notEmpty(_mutex)
     ,_flag(true)
{

}

TaskQueue::~TaskQueue(){

}

bool TaskQueue::empty() const{
    return 0 == _que.size();
}

bool TaskQueue::full() const{
    return _queSize == _que.size();
}

void TaskQueue::push(ElemType elem){
    _mutex.lock();

    while(full()){
        _notFull.wait();
    }
    _que.push(elem);
    _notEmpty.notify();

    _mutex.unlock();
}

ElemType TaskQueue::pop(){
    _mutex.lock();

    //子线程睡眠条件+_flag为true
    while(empty() && _flag){
        _notEmpty.wait();
    }

    if(_flag){
        ElemType tmp = _que.front();
        _que.pop();
        _notFull.notify();

        _mutex.unlock();
        return tmp;
    }else{
        _mutex.unlock();
        return NULL;
    }        
}

void TaskQueue::wakeup(){
    _flag = false;
    _notEmpty.notifyAll();
}

}//end of namespace tp
